#!/usr/bin/python
# -*- coding: utf-8 -*-
import os, sys,time,datetime
import paramiko,configparser
from queue import Queue,LifoQueue,PriorityQueue
import threading,os

event=threading.Event()
q=Queue(maxsize=150)
class SshConnectError(Exception):
    pass

class ssh_ctrl:
    def __init__(self,host,username,password,port=22):
        self.host=host
        self.ssh=ssh_ctrl.__sshConn(self.host,username,password,int(port))
        self.sftp=self.__sftpConn()

    def close(self):
        if hasattr(self.ssh,"close"):
            self.ssh.close()

    @staticmethod
    def __sshConn(host,username,password,port):
        ssh=paramiko.SSHClient()   ##创建一个SSH客户端client对象
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        try:
            ssh.connect(hostname=host,port=int(port),username=username,password=password)
            print("SSH %s 连接成功"%host)
        except:
            raise SshConnectError("SSH Connect %s Error!"% host)
        return ssh

    #返回sftp管道实例对象方法
    def __sftpConn(self):
        transport = self.ssh.get_transport() ##先SSH连上，再建立管道连接
        sftp=paramiko.SFTPClient.from_transport(transport) #创建一个已连通的SFTP客户端通道
        return sftp

    #执行命令方法
    def exeCommand(self,cmd,timeout=300):
        stdin,stdout,stderr=self.ssh.exec_command(cmd,timeout=timeout)
        try:
            channel=stdout.channel
            exit_code=channel.recv_exit_status()
            #报错返回127，没有报错返回0
            stdout=stdout.read().strip()
            stderr=stderr.read().strip()
            return {"status":1,"stdout":stdout,"stderr":stderr,"exit_code":exit_code}
        except:
            return {"status":0,"stdout":stdout,"stderr":stderr,"exit_code":127}

    @staticmethod
    def iter_local_path(abs_path):
        ##遍历本机目录，并返回
        result=set([])
        for path,dirs,files in os.walk(abs_path):
            # print(j)
            # for dir in dirs:
            #     print(dir)
            for file in files:
                file_path=os.path.join(path,file)
                result.add(file_path)
        return result
   
    def iter_remote_path(self,abs_path):
        set_list=set()
        shell_list=self.exeCommand("cd %s;./getdir.sh;cat path.txt"%abs_path)["stdout"].decode(encoding='utf-8').splitlines()
        # print(shell_list)
        for path in shell_list:
            # print(path)
            str_path=os.path.join(abs_path,path).replace(r'\.//','/')
            str_path=str_path.replace(r'\./','/')
            if('.' in str_path):
                set_list.add(str_path)
        # print(set_list)
        return set_list

    #文件上传下载方法
    def sftpFile(self,remotepath,localpath,action):
        try:
            if action =='push':
                # dir=os.path.split(remotepath)[0]
                dir = os.path.dirname(remotepath)
                # print(dir)
                self.exeCommand("mkdir -p %s"%dir)      #根据远程路径新建目录
                self.sftp.put(localpath,remotepath)
                return {"status":1,"message":"sftp %s %s 上传成功！"%(self.host,action)}
            elif action=="pull":
                self.sftp.get(remotepath,localpath)
                return {"status":1,"message":"sftp %s %s 下载成功！"%(self.host,action),"stderr":""}
        except Exception as e:
            return {"status":0,"message":"sftp %s %s 失败！%s "%(self.host,action,str(e)),"stdout":""}


def download_file(host,username,password,remotepath,localpath):
    x=ssh_ctrl(host,username,password)
    remote=os.path.dirname(remotepath)
    now1=datetime.datetime.now().strftime("%Y-%m-%d%H:%M:%S")
    cmd="cd %s;tar -cvf log.tar %s"%(remote,remote)
    n=x.exeCommand(cmd)["stdout"].decode(encoding='utf-8').splitlines()
    localpath=remotepath.replace(remote,localpath)
    a=x.sftpFile(remotepath=remotepath,localpath=localpath,action="pull")
    now=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    str2="[{}] start download.{} >>> {}".format(now,remotepath,localpath)
    # print(a,str2)
    q.put((a,str2),block=True,timeout=None)
    event.set()
    b=x.exeCommand("rm -rf %s"%remotepath)["stdout"].decode(encoding='utf-8').splitlines()
    # print(b[0])

def upload_files(host,username,password,remotepath,localpath):
    x=ssh_ctrl(host,username,password)
    if q.full():
        time.sleep(0.01)
        pass
    else:
        n0=x.exeCommand("cd %s;rm -rf audio;echo old audio has removed!"%remotepath)["stdout"].decode(encoding='utf-8').splitlines()
        now=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        str2="[{}] 文件开始上传，请耐心等待...".format(now)
        # q.put((n,str2),block=True,timeout=None)  
        # event.set()                    
        for l in x.iter_local_path(localpath):
            remote1=os.path.join(remotepath,os.path.basename(l))
            remote1=remote1.replace('\\','/')
            x.sftpFile(localpath=l,remotepath=remote1,action="push")
        n=x.exeCommand("cd %s;ls -l |grep '^-'|wc -l"%remotepath)["stdout"].decode(encoding='utf-8').splitlines()
        n1=host+"文件上传完成，一共上传了"+n[0]+"个音频文件。"
        q.put((n0,str2,n1),block=True,timeout=None)
        event.set()

def write_config(config_dict):
    config=configparser.ConfigParser()
    config.read_dict(config_dict)

    with open('./config.ini','w') as configfile:
        config.write(configfile)

def read_config():
    config=configparser.ConfigParser()
    conf=config.read('./config.ini')

    return config



if __name__=='__main__':
    pass